#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using UTable.Objects.Controls;
using UTable.Input;
using UTable.Input.MultiTouch;
using System.IO;
using UTable.ObjectManager.Commands;
using UTable.Objects.Policies;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using UTable.Objects.Config;
using UTable.Config;

namespace UTable.Objects
{
    /// <summary>
    /// Interaction logic for UTableContent.xaml
    /// </summary>
    public partial class UMeeting : UTabletop
    {
        private WorkspaceLayoutCalculator layoutCalculator = new WorkspaceLayoutCalculator();

        private UMeetingConfig config = new UMeetingConfig();

        public static List<IObject> WorkspaceList { get; set; }

        public static int WorkspaceCount { get; set; }

        public static bool HasChairman { get; set; }

        public static List<Color> ColorList { get; set; }

        public static Color AnonymousUserColor = Colors.Blue;

        public static Color GetColor(int userId)
        {
            if (userId < 0)
                return AnonymousUserColor;
            else
                return ColorList[userId];
        }

        public UMeeting()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(UMeeting_Loaded);

            // Load the config file
            try
            {
                config = ObjectXMLSerializer<UMeetingConfig>.Load("UMeeting.config");
            }
            catch (System.Exception e)
            {
                config = null;
            }

            WorkspaceList = new List<IObject>();
            ColorList = new List<Color>();
            ColorList.Add(Colors.Blue);
            ColorList.Add(Colors.Green);
            ColorList.Add(Colors.Red);
            ColorList.Add(Colors.Brown);
            ColorList.Add(Colors.Pink);
            ColorList.Add(Colors.Plum);
            ColorList.Add(Colors.Purple);
            ColorList.Add(Colors.BurlyWood);
        }

        void UMeeting_Loaded(object sender, RoutedEventArgs e)
        {
            if (config != null)
            {
                // load applications
                foreach (LoadAppConfig app in config.Applications)
                {
                    UAppLoader.LoadApplication(app.FileLocation, app.Position, app.Orientation, this);
                }
            }
        }

		protected override void OnCreatePhysicalPolicy(PhysicalLayoutPolicyParameter parameter)
		{
		}

        protected override void OnMenuShowing(UElementMenu menu)
        {
            base.OnMenuShowing(menu);

            UElementMenuItem layoutItem = new UElementMenuItem();
            layoutItem.Header = "Customize Layout";
            layoutItem.Command = "CustomizeLayout";
            menu.Items.Add(layoutItem);
            this.TipBlock.Opacity = 0;
        }

        protected override void OnCommandReceived(UElementMenu sender, ElementMenuCommandReceivedEventArgs args)
        {
            base.OnCommandReceived(sender, args);

            switch (args.Command)
            {
                case "CustomizeLayout":
                    ObjectCreateParameter customizerParam = new ObjectCreateParameter(typeof(ULayoutCustomizer));
                    IObject customizer = UTableHelper.CreateObject(customizerParam);
                    customizer.Position = MenuPositionList[sender];
                    customizer.Owner = this;
                    break;
            }
        }

        protected override void OnMenuClosed(UElementMenu menu)
        {
            base.OnMenuClosed(menu);
        }

        public override void OnMessageReceived(object message)
        {
            base.OnMessageReceived(message);

            if (message is UpdateLayoutMessage)
            {
                UpdateLayoutMessage msg = message as UpdateLayoutMessage;
                UpdateLayout(msg.WorkspaceNumber, msg.HasChairman, msg.Direction);
            }
        }

        private void OnCreateWorkspace(Point spacePosition, Size spaceSize, double spaceOrientation)
        {
            ObjectCreateParameter param = new ObjectCreateParameter(typeof(UWorkspace));
            IObject workspace = UTableHelper.CreateObject(param);
            workspace.Position = spacePosition;
            workspace.Width = spaceSize.Width;
            workspace.Height = spaceSize.Height;
            workspace.Orientation = spaceOrientation;
            workspace.Owner = this;

            workspace.SendMessage(new SetWorkspaceNumberMessage("No." + WorkspaceList.Count));
            WorkspaceList.Add(workspace);
        }

        /// <summary>
        /// Update the layout of the tabletop according to the given parameters
        /// </summary>
        public void UpdateLayout(int workspaceNumber, bool hasChariman, LayoutDirection direction)
        {
            this.ClearTable_Button_Pressed(null, null);
            WorkspaceCount = workspaceNumber;
            HasChairman = hasChariman;
            layoutCalculator.UpdateLayout(
                workspaceNumber,
                hasChariman,
                direction,
                new Size(this.Width, this.Height),
                new WorkspaceLayoutCalculator.CreateWorkspaceHandler(OnCreateWorkspace));
        }


        private void CloseApps_Button_Pressed(object sender, ButtonEventArgs args)
        {
            UTableHelper.Shutdown(0);
        }

        private void ClearTable_Button_Pressed(object sender, ButtonEventArgs args)
        {
            ClearTabletop();
            WorkspaceList.Clear();
            WorkspaceCount = 0;
        }
    }
}
